function HT_Entity(){
	this.attribute = new Array();
	this.topic = new Array();
	this.resource = new Array();
	this.relatedEntity = new Array();
	this.bFragment = false;
	this.fragmentContent = "";
	this.colorIndex = 0;
	this.entityUri = null;
	this.entityName = null;
};

HT_Entity.prototype = {
	addAttribute: function(name, value){
		var attr = {};
		attr.name = name;
		attr.value = value;
		
		if(name=="type" && value=="fragment")
			this.bFragment = true;
		if(name=="name"){
			this.fragmentContent = value;
			this.entityName = value;
		}
		if(name=="colorIndex")
			this.colorIndex = value;
		this.attribute.push(attr);
	},
	
	addTopic: function(href){
		var t = {};
		t.href = href;
		this.topic.push(t);
	},
	
	addResource: function(name, href){
		var res = {};
		res.name = name;
		res.href = href;
		
		this.resource.push(res);
	},
	
	addRelatedEntity: function(uri){
		var re = {};
		re.href = uri;
		debug("[xml.js] relatedEntity Url:" + re.href,4)
		re.relationType = "partOf";
		this.relatedEntity.push(re);
	},
	
	isFragment: function(){
		return this.bFragment;
	},
	
	getFragmentContent: function(){
		return this.fragmentContent;
	}
};

var entityParser = {
	xmlReader: null,
	entity: null,
	
	init: function(){
		entity = new HT_Entity();
		
		xmlReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"]
                          .createInstance(Components.interfaces.nsISAXXMLReader);
                          
    xmlReader.contentHandler = {
	  	// nsISAXContentHandler
		  startDocument: function() {
		    //debug("startDocument");
		  },
		  
		  endDocument: function() {
		    //debug("endDocument");
		  },
		  
		  startElement: function(uri, localName, qName, /*nsISAXAttributes*/ attributes) {
		    var key, value;
		    if(qName == "attribute"){
		    	
		    	for(var i=0; i<attributes.length; i++) {
		    		if(attributes.getQName(i) == "name")
		    			key = attributes.getValue(i);
		    		if(attributes.getQName(i) == "value")
		    			value = attributes.getValue(i);
		    	}
		    	entity.addAttribute(key,value);
		    }
		    
		    if(qName == "resource"){
		    	for(var i=0; i<attributes.length; i++) {
		    		if(attributes.getQName(i) == "name")
		    			key = attributes.getValue(i);
		    		if(attributes.getQName(i) == "href")
		    			value = attributes.getValue(i);
		    	}
		    	entity.addResource(key,value);
		    }
		    
		    if(qName == "topic")
		    	for(var i=0; i<attributes.length; i++) {
		    		if(attributes.getQName(i) == "href")
		    			entity.addTopic(attributes.getValue(i));
		    	}
		    
		    if(qName == "relatedEntity")
		    	for(var i=0; i<attributes.length; i++) {
		    		if(attributes.getQName(i) == "href")
		    			entity.addRelatedEntity(attributes.getValue(i));
		    	}
		  },
		  
		  endElement: function(uri, localName, qName) {
		    //debug("endElement: namespace='" + uri + "', localName='" + 
		    //      localName + "', qName='" + qName + "'");
		  },
		  
		  characters: function(value) {
		    //debug("characters: " + value);
		  },
		  
		  processingInstruction: function(target, data) {
		    //debug("processingInstruction: target='" + target + "', data='" + data + "'");
		  },
		  
		  ignorableWhitespace: function(whitespace) {
		    // don't care
		  },
		  
		  startPrefixMapping: function(prefix, uri) {
		    // don't care
		  },
		  
		  endPrefixMapping: function(prefix) {
		    // don't care
		  },
		  
		  // nsISupports
		  QueryInterface: function(iid) {
		    if(!iid.equals(Components.interfaces.nsISupports) &&
		       !iid.equals(Components.interfaces.nsISAXContentHandler))
		      throw Components.results.NS_ERROR_NO_INTERFACE;
		    return this;
		  }
		};
	},
	
	parser: function(str){
		xmlReader.parseFromString(str, "text/xml");
		return entity;
	}
};

var entitySerialize = {
	serialize: function(obj){
		var xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
		xmlStr += "<!DOCTYPE entity SYSTEM \"" + ENTITY_DTD + "\">\n";
		xmlStr += "<entity>\n";
		for(i = 0; i < obj.attribute.length; i++){
			var k = obj.attribute[i].name + "";
			var v = obj.attribute[i].value + "";
			xmlStr += "<attribute name=\"" + k.toXml() + "\" value=\"" + v.toXml() + "\" />";
		}
		for(i = 0; i < obj.resource.length; i++){
			var k = obj.resource[i].name + "";
			var v = obj.resource[i].href + "";
			xmlStr += "<resource name=\"" + k.toXml() + "\" href=\"" + v.toXml() + "\" />";
		}
		for(i = 0; i < obj.topic.length; i++){
			var h = obj.topic[i].href + "";
			xmlStr += "<topic href=\"" + h.toXml() + "\" />";
		}
		for(i = 0; i < obj.relatedEntity.length; i++){
			var h = obj.relatedEntity[i].name + "";
			var rt = obj.relatedEntity[i].relationType + "";
			xmlStr += "<relatedEntity href=\"" + h.toXml() + "\" relationType=\"" + rt.toXml() + "\" />";
		}
		xmlStr += "</entity>";
		return xmlStr;
	}
};

function HT_Resource(){
	this.entities = new Array();
	this.resourceUri = null;
};
HT_Resource.prototype = {
	addEntity: function(href){
		for each (var entity in this.entities)
			if(entity.href == href)
				return true;
		var entity = {};
		entity.href = href;
		this.entities.push(entity);
		return true;
	}
}
var resourceParser = {
	xmlReader: null,
	resource: null,
	
	init: function(){
		resource = new HT_Resource();
		
		xmlReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"]
                          .createInstance(Components.interfaces.nsISAXXMLReader);
                          
    xmlReader.contentHandler = {
	  	// nsISAXContentHandler
		  startDocument: function() { },
		  endDocument: function() {},
		  startElement: function(uri, localName, qName, /*nsISAXAttributes*/ attributes) {
		    var key, value;
		    
		    if(qName == "resource"){
		    	for(var i=0; i<attributes.length; i++)
		    		if(attributes.getQName(i) == "href")
		    			resource.resourceUri = attributes.getValue(i);
		    }
		    
		    if(qName == "entity"){
		    	for(var i=0; i<attributes.length; i++) 
		    		if(attributes.getQName(i) == "href")
		    			resource.addEntity(attributes.getValue(i));
		    }
		  },
		  
		  endElement: function(uri, localName, qName) {},
		  characters: function(value) {},
		  processingInstruction: function(target, data) {},
		  ignorableWhitespace: function(whitespace) {},
		  startPrefixMapping: function(prefix, uri) {},
		  endPrefixMapping: function(prefix) {},
		  
		  // nsISupports
		  QueryInterface: function(iid) {
		    if(!iid.equals(Components.interfaces.nsISupports) &&
		       !iid.equals(Components.interfaces.nsISAXContentHandler))
		      throw Components.results.NS_ERROR_NO_INTERFACE;
		    return this;
		  }
		};
	},
	
	parser: function(str){
		xmlReader.parseFromString(str, "text/xml");
		return resource;
	}
};

function HT_Topic(){
	this.topicUri = null;
	this.topicName = null;
	this.viewpointUri = null;
	this.viewpointName = null;
	this.relatedTopics = new Array();
	this.entities = new Array();
	this.resourceUri = null;
};

HT_Topic.prototype = {
	addRelatedTopic: function(relatedTopic){
		if(relatedTopic == null || relatedTopic.href == null)
			return false;
			
		for each (var topic in this.relatedTopics)
			if(topic.href == relatedTopic.href)
				return true;
				
		this.relatedTopics.push(relatedTopic);
		return true;
	},
	
	addEntity: function(el){
		if(el == null || el.href == null)
			return false;
		
		for each (var entity in this.entities)
			if(entity.href == el.href)
				return true;
		
		this.entities.push(el);
		return true;
	}
}
var topicParser = {
	xmlReader: null,
	topic: null,
	entity: null,
	currentElement: null,
	
	init: function(){
		topic = new HT_Topic();
		
		xmlReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"]
                          .createInstance(Components.interfaces.nsISAXXMLReader);
                          
    xmlReader.contentHandler = {
	  	// nsISAXContentHandler
		  startDocument: function() { },
		  endDocument: function() {},
		  startElement: function(uri, localName, qName, /*nsISAXAttributes*/ attributes) {
		  	currentElement = qName;
		    if(qName == "topic"){
		    	for(var i=0; i<attributes.length; i++){
		    		if(attributes.getQName(i) == "href")
		    			topic.topicUri = attributes.getValue(i);
		    		if(attributes.getQName(i) == "name")
		    			topic.topicName = attributes.getValue(i);
		    	}
		    }
		    if(qName == "viewpoint"){
		    	for(var i=0; i<attributes.length; i++){
		    		if(attributes.getQName(i) == "href")
		    			topic.viewpointUri = attributes.getValue(i);
		    	}
		    }
		    if(qName == "entity"){
		    	entity = {};
		    	for(var i=0; i<attributes.length; i++) 
		    		if(attributes.getQName(i) == "href")
		    			entity.href = attributes.getValue(i);
		    }
		    
		    if(qName == "relatedTopic"){
		    	relatedTopic  = {};
		    	for(var i=0; i<attributes.length; i++){ 
		    		if(attributes.getQName(i) == "href")
		    			relatedTopic.href = attributes.getValue(i);
		    		if(attributes.getQName(i) == "relationType")
		    			relatedTopic.relationType = attributes.getValue(i);
		    	}
		    }
		  },
		  
		  endElement: function(uri, localName, qName) {
		  	if(currentElement == "entity"){
		  		topic.addEntity(entity);
		  		entity = null;
		  	}
		  	if(currentElement == "relatedTopic"){
		  		topic.addRelatedTopic(relatedTopic);
		  		relatedTopic = null;
		  	}
		  	currentElement = null;
		  },
		  characters: function(value) {
		  	if((typeof currentElement) != "string")
		  		return;
		  	if(currentElement == "entity"){
		  		entity.name = value;
		  	}	
		  	if(currentElement == "relatedTopic"){
		  		relatedTopic.name = value;
		  	}
		  	
		  	if(currentElement == "viewpoint"){
		  		topic.viewpointName = value;
		  	}
		  },
		  processingInstruction: function(target, data) {},
		  ignorableWhitespace: function(whitespace) {},
		  startPrefixMapping: function(prefix, uri) {},
		  endPrefixMapping: function(prefix) {},
		  
		  // nsISupports
		  QueryInterface: function(iid) {
		    if(!iid.equals(Components.interfaces.nsISupports) &&
		       !iid.equals(Components.interfaces.nsISAXContentHandler))
		      throw Components.results.NS_ERROR_NO_INTERFACE;
		    return this;
		  }
		};
	},
	
	parser: function(str){
		xmlReader.parseFromString(str, "text/xml");
		return topic;
	}
};




/* **************************************************************************************************************** */
function topicXmlTesting(){
var topicXmlExample = '<?xml version="1.0" encoding="UTF-8"?>'
 + '<!DOCTYPE topic SYSTEM "http://tech-ada.utt.fr/validator/dtd/topic.dtd">'
 + '<topic name="World Wide Web">'
 + '<viewpoint href="http://tech-ada.utt.fr/viewpoint/1/">Software features</viewpoint>'
 + '<relatedTopic relationType="includes" href="http://tech-ada.utt.fr/viewpoint/1/topic/2/">Web browser</relatedTopic>'
 + '<relatedTopic relationType="includes" href="http://tech-ada.utt.fr/viewpoint/1/topic/3/">Web server</relatedTopic>'
 + '<entity href="http://tech-ada.utt.fr/entity/www/">html specification</entity>'
 + '<entity href="http://tech-ada.utt.fr/entity/w3c/">w3c</entity>'
 + '</topic>';
topicParser.init();
var topic = topicParser.parser(topicXmlExample);
debug("topic:" + topic.topicUri + "," + topic.topicName , 2);
debug("viewpoint:" + topic.viewpointUri + "," + topic.viewpointName , 2);
for each(var rtopic in topic.relatedTopics)
	debug("relatedTopic:" + rtopic.href + "," + rtopic.name + "," + rtopic.relationType, 2);
for each(var entity in topic.entities)
	debug("entity:" + entity.href + "," + entity.name , 2);
}

function resourceXmlTesting(){
var resourceXmlExample = '<?xml version="1.0" encoding="UTF-8"?>'
+'<!DOCTYPE value SYSTEM "http://tech-ada.utt.fr/validator/dtd/resource.dtd">'
+'<resource href="http://tech-ada.utt.fr/resource.htm">'
+'    <entity href="http://tech-ada.utt.fr/entity/JIGSAW/" />'
+'</resource>';
resourceParser.init();
var resource = resourceParser.parser(resourceXmlExample);
debug("resource:" + resource.resourceUri);
for each(var entity in resource.entities)
	debug("entity:" + entity.href);
}

function entityXmlTesting(){
var entityXmlExample = '<?xml version="1.0" encoding="UTF-8"?>'
 + '<!DOCTYPE entity SYSTEM "http://tech-ada.utt.fr/validator/dtd/entity.dtd">'
 + '<entity>'
 + '    <attribute name="name" value="Amaya - W3C\'s Editor &amp; Browser" />'
 + '    <attribute name="type" value="software" />'
 + '    <attribute name="license" value="W3C Software Notice and License" />'
 + '    <attribute name="program language" value="C" />'
 + '    <attribute name="program language" value="C++" />'
 + '    <attribute name="last release" value="2006-02-10" />'
 + '    <attribute name="project site" value="http://www.w3.org/Amaya/" />'
 + '    <resource name="original" href="http://tech-ada.utt.fr/resource.doc" />'
 + '    <resource name="HTMLVersion" href="http://tech-ada.utt.fr/resource.htm" />'
 + '    <topic href="http://tech-ada.utt.fr/viewpoint/1/topic/1/">World Wide Web</topic>'
 + '    <relatedEntity href="http://tech-ada.utt.fr/entity/download/hypertopicprotocolstandard/" relationType="partOf"/>'
 + '    <relatedEntity href="http://tech-ada.utt.fr/entity/download/RESTClient/" relationType="partOf"/>'
 + '</entity>';

entityParser.init();
debug("XML parser");
var entity = entityParser.parser(entityXmlExample);
for(i =0; i < entity.attribute.length; i++)
	debug("attribute:" + entity.attribute[i].name + "," + entity.attribute[i].value);
for(i =0; i < entity.topic.length; i++)
	debug("topic:" + entity.topic[i].href); 
for(i =0; i < entity.resource.length; i++)
	debug("resource:" + entity.resource[i].name + "," + entity.resource[i].href);
for(i =0; i < entity.relatedEntity.length; i++)
	debug("relatedEntity:" + entity.relatedEntity[i].href);

entity.addAttribute("name", "testing");
entity.addAttribute("type", "fragment");
entity.addAttribute("colorIndex", "2");

debug("XML Serialize");
debug(entitySerialize.serialize(entity));
}

function entityTesting(){
	var myEntity = new HT_Entity();
	myEntity.addAttribute("name", "test1");
	for(var j =0; j < myEntity.attribute.length; j++)
			debug(myEntity.attribute[j].name + "," + myEntity.attribute[j].value);
	
	debug("new entity");
	myEntity = new HT_Entity();
	myEntity.addAttribute("name", "test2");
	for(var j =0; j < myEntity.attribute.length; j++)
			debug(myEntity.attribute[j].name + "," + myEntity.attribute[j].value);
}